package cn.flying.cloud.base.oss.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import io.minio.MinioClient;

import cn.flying.cloud.base.oss.awss3.AwsS3Template;
import cn.flying.cloud.base.oss.minio.MinioTemplate;

/**
 * oss配置bean
 *
 * @author: admin
 * @date: 2023年07月12日 21:42
 * @version: 1.0
 */
@Configuration
@EnableConfigurationProperties(OssProperties.class)
public class OssAutoConfiguration {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 基于s3的oss客户端配置
     *
     * @param ossProperties
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.oss", name = "type", havingValue = "S3")
    public AmazonS3 amazonS3Client(OssProperties ossProperties) {
        try {
            // 客户端配置，主要是全局的配置信息
            ClientConfiguration clientConfiguration = new ClientConfiguration();
            clientConfiguration.setMaxConnections(ossProperties.getMaxConnections());
            // url以及region配置
            AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(ossProperties.getEndpoint(), ossProperties.getRegion());
            // 凭证配置
            AWSCredentials awsCredentials = new BasicAWSCredentials(ossProperties.getAccessKey(), ossProperties.getSecretKey());
            AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
            // build amazonS3Client客户端
            AmazonS3 amazonS3 = AmazonS3Client.builder().withEndpointConfiguration(endpointConfiguration)
                    .withClientConfiguration(clientConfiguration).withCredentials(awsCredentialsProvider)
                    .disableChunkedEncoding().withPathStyleAccessEnabled(ossProperties.getPathStyleAccess()).build();
            logger.info("AmazonS3Client客户端连接到minio服务器：{}，accessKey：{}", ossProperties.getEndpoint(), ossProperties.getAccessKey());
            return amazonS3;
        } catch (Exception e) {
            logger.error("AmazonS3Client客户端初始化异常", e);
            return null;
        }
    }

    /**
     * 配置AwsS3Template bean对象
     *
     * @param amazonS3
     * @return
     */
    @Bean
    @ConditionalOnBean(AmazonS3.class)
    public AwsS3Template awsS3Template(AmazonS3 amazonS3) {
        return new AwsS3Template(amazonS3);
    }

    /**
     * 基于minio的oss客户端配置
     *
     * @param ossProperties
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.oss", name = "type", havingValue = "minio")
    public MinioClient minioClient(OssProperties ossProperties) {
        try {
            MinioClient minioClient = MinioClient.builder().endpoint(ossProperties.getEndpoint()).credentials(ossProperties.getAccessKey(), ossProperties.getSecretKey()).build();
            // 忽略证书校验，防止自签名证书校验失败导致无法建立连接
            minioClient.ignoreCertCheck();
            logger.info("MinioClient客户端连接到minio服务器：{}，accessKey：{}", ossProperties.getEndpoint(), ossProperties.getAccessKey());
            return minioClient;
        } catch (Exception e) {
            logger.error("MinioClient客户端初始化异常", e);
            return null;
        }
    }

    /**
     * 配置MinioTemplate bean对象
     *
     * @param minioClient
     * @return
     */
    @Bean
    @ConditionalOnBean(MinioClient.class)
    public MinioTemplate minioTemplate(MinioClient minioClient) {
        return new MinioTemplate(minioClient);
    }
}